package fr.nghs.android.thport.gestures;

import android.util.Log;
import fr.nghs.android.common.MathUtils;
import fr.nghs.android.common.ScaleGestureDetector;
import fr.nghs.android.thport.THSurface;

/**
 * Surface progressive zoom & offset
 * Using 2 fingers pinch-to-zoom
 * @author ng
 *
 */
public class SurfaceMoveAndScale
    implements ScaleGestureDetector.OnScaleGestureListener
{
    private static final float ZOOM_MINMAL_STEP = 0.12f;
    private static final float ZOOM_MINMIUM = 1.07f;
    private static final float ZOOM_MAXIMUM = 2.00f;
    //private static final float ZOOM_CORRECTION_FACTOR = 0.6f;
    
    private float prevX, prevY;
    private float rawZoom = 1f, zoom = 1f;
    private int xOffset = 0, yOffset = 0, w, h;

    private THSurface surface;
    
    public SurfaceMoveAndScale(THSurface s)
    {
        surface = s;
    }
    
    @Override
    public boolean onScaleBegin(ScaleGestureDetector s)
    {
        prevX = Float.NaN;
        w = surface.getWidth();
        h = surface.getHeight();
        return true;
    }
    
    @Override
    public boolean onScale(ScaleGestureDetector s)
    {
        final float x = s.getFocusX();
        final float y = s.getFocusY();
        final float z = s.getScaleFactor();// * ZOOM_CORRECTION_FACTOR;
        
        final float newZoom;
        
        rawZoom *= z;
        if(rawZoom <= ZOOM_MINMIUM)
            newZoom = rawZoom = 1f;
        else if(rawZoom >= ZOOM_MAXIMUM)
            newZoom = rawZoom = ZOOM_MAXIMUM;
        else
            newZoom = rawZoom - (ZOOM_MINMIUM - 1f);

        if(MathUtils.abs(zoom - newZoom) > ZOOM_MINMAL_STEP)
            zoom = newZoom;

        Log.d("NGHS", "z=" + z + "\t zoom=" + zoom + "\t rawZoom=" + rawZoom + "\t newZoom=" + newZoom);
            

        boolean isFirst = Float.isNaN(prevX);
        
        if(isFirst)
        {
        }
        else
        {
            xOffset += x - prevX;
            yOffset += y - prevY;
            
            //Log.d("NGHSTH", "w="+w+" zoom="+zoom+" w*zoom="+(w*zoom) + " w*(1-zoom)=" +(int)(w * (1 - zoom)) + " xoffset="+xOffset+ " yoffset="+yOffset);
            
            yOffset = MathUtils.ensureRange(yOffset, (int)(h * (1 - zoom)), 0);
            xOffset = MathUtils.ensureRange(xOffset, (int)(w * (1 - zoom)), 0);

            surface.setOffsetAndScale(xOffset, yOffset, zoom);
        }
        
        prevX = x;
        prevY = y;
        return true;

    }

    @Override
    public void onScaleEnd(ScaleGestureDetector s)
    {
    }

}
